第10週 catコマンドの自作
Source : execute on your shell
alias cat="echo 'にゃーん。'"
Result : にゃーん。
↑のようなコマンドは癒やされますが実行しない方が良いでしょう。
今週の内容
catコマンドの自作
今週は特に全体で進めていくべき内容はないので各自でプログラムを書いていってください。とくに答えとなるプログラムも載せないことにします。(練習も兼ねてGit管理すると良いと思います)
catコマンドは引数で与えられたファイルの内容を標準出力に出力するコマンドです。
オプションで細かい指定もできますが、ここではオプションのことを気にせず、cat hello.cでhello.cのソースコードが出力されるだけのプログラムを作りましょう。
必要となる知識
コマンドライン引数
ファイルのオープン・クローズ
マクロ
実装
catコマンドが行うことは基本的には次の3つです
ファイルをオープンする
ファイルから中身を読み出して文字列に格納する
その文字列を出力する
まずはこの部分の実装を目指しましょう。文字列のバッファサイズはファイルの先頭にdefineマクロで宣言しておくのが慣例です。
また、引数の数が足りなかったり多かったりする場合はその時点でエラー処理を行いましょう。
即座に関数からreturnしてプログラムを終了します。
エラー時に文字列を出力する場合は標準出力の代わりに標準エラー出力を用いたほうが良いでしょう。
引数がなかった場合早期リターンで終了するエラー処理の例
code:errorExit.c
int main(int argc, char *argv[]) {
if(argc != 2) {
fprintf(stderr, "Usage: cat <filename>\n");
return 1;
}
return 0;
}
return 1でこのプログラムが異常終了していることを表しています。
異常終了とはどういうことでしょうか?少し深堀りしてみます。
正規のcatコマンドで例を見てみましょう。通常通りcatを実行するとプログラムの終了ステータスは0となっています。
code:例
cat hello.c
int main(void) {
printf("hello, world!\n");
return 0;
}
echo $?
0
bashやzshでは$?というshellの変数に最後の終了ステータスが格納されています。echoコマンドは文字列や変数の値を出力するためのコマンドであり、こういった変数の値を確認する際やファイルに文字列を書き込むときなどにパイプなどとともに利用されます。
存在しないファイルを開こうとすれば、catは当然エラーを表示し出力をスキップして終了します。
code:例
cat noexist.c
cat: noexist.c: no such file or directory
echo $?
1
このように、プログラムが正常に終了しなかった場合終了ステータスは0ではない数値が返ってきます。異常終了を示す値としては1が多いですが-1や2以上の数値が使われることもあります。基本的にはどんな数値を使っても問題はないですが0でなければすべて異常終了です。終了ステータスは0~255しか扱えないので-1を返すと255が返ってきます(ピンとこない人は2の補数表記について調べてください)。そのため、終了ステータスの値も0~255の間でreturnするのが行儀が良いとされます。
次に、ファイルから中身を読み取って文字列に格納しましょう。ファイルの扱い方については第9回で学習しているはずです。
ファイルの中身の文字列が用意できればあとはそれを出力するだけです。これで一通りの動作はできるようになったと言えるでしょう。
それでは、この自作catコマンドを本家を参考に高機能化していきます。
やること
複数ファイルの出力に対応しましょう。cat a.c b.c c.cなどと実行するとそれぞれのファイルの中身を続けて出力します。途中でエラーが発生してもそれ以降の処理は続けます。(例えばb.cが存在しなかったとしてもエラーメッセージを出力しつつc.cの処理に移る)
-nオプションを渡すと行番号を表示できるようにしましょう。複数ファイルを読む場合は行番号はそのまま継続して出力します(a.cで3行出力した場合b.cの1行目の行番号は4)。
引数がない場合や-である場合、ファイルを開く代わりに標準入力を標準出力にコピーします(ピンとこない場合は自分でcat -を試してみてください)。EOF文字(C-dで入力)が来ると終了します。
その他何らかの独自機能(cat --helpで出てきた機能の中で好きなやつ実装したら良いと思います)
後期第1週目の活動で1回生の作った自作catコマンドの発表的なものをしてもらうので、
簡単なものでいいので資料作成お願いします。形式は問わないですけどまあスライドがかたそうですね。
また、完成したらGitHubのリポジトリのリンクをC言語班のチャンネルに貼っといてもらえるとレビューなどが捗ります。
以下、発表内容です
機能
プログラムの設計
工夫した点(別になくてもいいですけど)